import {
  Controller,
  Post,
  Get,
  Body,
  Param,
  Query,
  UseGuards,
  BadRequestException,
} from '@nestjs/common';
import { ApiOperation, ApiTags } from '@nestjs/swagger';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';

import { UserEntity } from '@/types/modules/user/entities/user.entity';

import { VersionControlService } from './version-control.service';
import { EditorService } from './editor.service';
import { LcProject } from '../types/editor.type';
import { JwtAuthGuard } from '@/modules/user/jwt/jwt-auth.guard';
import { CurrentUser } from '@/decorators/current.user';

@ApiTags('版本控制')
@Controller('version-control')
export class VersionControlController {
  constructor(
    private versionControlService: VersionControlService,
    private editorService: EditorService,
    @InjectModel('project') private projectModel: Model<LcProject>,
  ) {}

  @ApiOperation({ summary: '初始化项目版本控制' })
  @UseGuards(JwtAuthGuard)
  @Post('init')
  async initVersionControl(
    @Body() params: { projectId: string },
    @CurrentUser() u: UserEntity,
  ) {
    const { projectId } = params;

    // 检查项目权限
    const project = await this.projectModel.findById(projectId);
    if (!project) {
      throw new BadRequestException('项目不存在');
    }
    const hasPermission = await this.editorService.checkAuth(
      project,
      'edit',
      u.id,
    );
    if (!hasPermission) {
      throw new BadRequestException('您无权操作该项目');
    }

    const initialCommit =
      await this.versionControlService.initializeVersionControl(
        projectId,
        u.id,
      );

    return {
      success: true,
      initialCommit,
      message: '版本控制初始化成功',
    };
  }

  @ApiOperation({ summary: '创建开发提交' })
  @UseGuards(JwtAuthGuard)
  @Post('commit')
  async createCommit(
    @Body()
    params: {
      projectId: string;
      message: string;
    },
    @CurrentUser() u: UserEntity,
  ) {
    const { projectId } = params;

    // 检查项目权限
    const project = await this.projectModel.findById(projectId);
    if (!project) {
      throw new BadRequestException('项目不存在');
    }
    const hasPermission = await this.editorService.checkAuth(
      project,
      'edit',
      u.id,
    );
    if (!hasPermission) {
      throw new BadRequestException('您无权操作该项目');
    }

    const commit = await this.versionControlService.createDevelopmentCommit({
      ...params,
      userId: u.id,
    });

    return {
      success: true,
      commit,
      message: '提交创建成功',
    };
  }

  @ApiOperation({ summary: '创建发布版本' })
  @UseGuards(JwtAuthGuard)
  @Post('release')
  async createRelease(
    @Body()
    params: {
      projectId: string;
      version: string;
      description: string;
      fromCommitId?: string;
    },
    @CurrentUser() u: UserEntity,
  ) {
    const { projectId } = params;

    // 检查项目权限
    const project = await this.projectModel.findById(projectId);
    if (!project) {
      throw new BadRequestException('项目不存在');
    }
    const hasPermission = await this.editorService.checkAuth(
      project,
      'edit',
      u.id,
    );
    if (!hasPermission) {
      throw new BadRequestException('您无权操作该项目');
    }

    const releaseCommit = await this.versionControlService.createRelease({
      ...params,
      userId: u.id,
    });

    return {
      success: true,
      release: releaseCommit,
      message: `发布版本 ${params.version} 创建成功`,
    };
  }

  @ApiOperation({ summary: '智能发布版本 - 自动初始化和版本号' })
  @UseGuards(JwtAuthGuard)
  @Post('smart-release')
  async smartRelease(
    @Body()
    params: {
      projectId: string;
      version?: string; // 可选：自定义版本号
      description?: string; // 可选：自定义描述
    },
    @CurrentUser() u: UserEntity,
  ) {
    const { projectId } = params;

    // 检查项目权限
    const project = await this.projectModel.findById(projectId);
    if (!project) {
      throw new BadRequestException('项目不存在');
    }
    const hasPermission = await this.editorService.checkAuth(
      project,
      'edit',
      u.id,
    );
    if (!hasPermission) {
      throw new BadRequestException('您无权操作该项目');
    }
    try {
      const releaseCommit = await this.versionControlService.smartRelease({
        ...params,
        userId: u.id,
      });
      return {
        success: true,
        release: releaseCommit,
        message: `发布版本 ${releaseCommit.releaseTag?.version} 创建成功`,
        autoInitialized: true, // 表示可能进行了自动初始化
      };
    } catch (e) {
      return {
        success: false,
        message: e.message,
        autoInitialized: false,
      };
    }
  }

  @ApiOperation({ summary: '获取提交历史' })
  @UseGuards(JwtAuthGuard)
  @Get('history/:projectId')
  async getCommitHistory(
    @Param('projectId') projectId: string,
    @Query('type') type?: 'development' | 'release' | 'hotfix',
    @Query('limit') limit?: number,
    @Query('skip') skip?: number,
    @CurrentUser() u?: UserEntity,
  ) {
    // 检查项目权限
    const project = await this.projectModel.findById(projectId);
    if (!project) {
      throw new BadRequestException('项目不存在');
    }
    const hasPermission = await this.editorService.checkAuth(
      project,
      'edit',
      u.id,
    );
    if (!hasPermission) {
      throw new BadRequestException('您无权访问该项目');
    }

    return this.versionControlService.getCommitHistory({
      projectId,
      type,
      limit: limit ? Number(limit) : undefined,
      skip: skip ? Number(skip) : undefined,
    });
  }

  @ApiOperation({ summary: '获取版本列表' })
  @UseGuards(JwtAuthGuard)
  @Get('versions/:projectId')
  async getVersions(
    @Param('projectId') projectId: string,
    @CurrentUser() u: UserEntity,
  ) {
    // 检查项目权限
    const project = await this.projectModel.findById(projectId);
    if (!project) {
      throw new BadRequestException('项目不存在');
    }
    const hasPermission = await this.editorService.checkAuth(
      project,
      'edit',
      u.id,
    );
    if (!hasPermission) {
      throw new BadRequestException('您无权访问该项目');
    }

    return this.versionControlService.getVersionList(projectId);
  }

  @ApiOperation({ summary: '获取工作区状态（类似 git status）' })
  @UseGuards(JwtAuthGuard)
  @Get('status/:projectId')
  async getWorkingStatus(
    @Param('projectId') projectId: string,
    @CurrentUser() u: UserEntity,
    @Query('compareWith') compareWith?: 'development' | 'release',
  ) {
    console.log('请求/staus/project');
    // 检查项目权限
    const project = await this.projectModel.findById(projectId);
    if (!project) {
      throw new BadRequestException('项目不存在');
    }
    const hasPermission = await this.editorService.checkAuth(
      project,
      'edit',
      u.id,
    );
    if (!hasPermission) {
      throw new BadRequestException('您无权访问该项目');
    }

    const status = await this.versionControlService.getWorkingStatus({
      projectId,
      userId: u.id,
      compareWith: compareWith || 'development',
    });

    return {
      success: true,
      ...status,
    };
  }

  @ApiOperation({ summary: '获取开发版本文件' })
  @UseGuards(JwtAuthGuard)
  @Get('development/:projectId')
  async getDevelopmentFiles(
    @Param('projectId') projectId: string,
    @CurrentUser() u: UserEntity,
  ) {
    // 检查项目权限
    const project = await this.projectModel.findById(projectId);
    if (!project) {
      throw new BadRequestException('项目不存在');
    }
    const hasPermission = await this.editorService.checkAuth(
      project,
      'edit',
      u.id,
    );
    if (!hasPermission) {
      throw new BadRequestException('您无权访问该项目');
    }

    return this.versionControlService.getDevelopmentFiles(projectId);
  }

  @ApiOperation({ summary: '获取发布版本文件' })
  @UseGuards(JwtAuthGuard)
  @Get('release/:projectId')
  async getReleaseFiles(
    @Param('projectId') projectId: string,
    @Query('version') version?: string,
    @CurrentUser() u?: UserEntity,
  ) {
    // 检查项目权限
    const project = await this.projectModel.findById(projectId);
    if (!project) {
      throw new BadRequestException('项目不存在');
    }
    const hasPermission = await this.editorService.checkAuth(
      project,
      'edit',
      u.id,
    );
    if (!hasPermission) {
      throw new BadRequestException('您无权访问该项目');
    }

    return this.versionControlService.getReleaseFiles(projectId, version);
  }

  @ApiOperation({ summary: '获取指定版本文件' })
  @UseGuards(JwtAuthGuard)
  @Get('files/:commitId')
  async getVersionFiles(
    @Param('commitId') commitId: string,
    @CurrentUser() u: UserEntity,
  ) {
    // 获取提交信息以检查权限
    const commit = await this.versionControlService['commitModel'].findById(
      commitId,
    );
    if (!commit) {
      throw new BadRequestException('提交不存在');
    }

    // 检查项目权限
    const project = await this.projectModel.findById(commit.projectId);
    if (!project) {
      throw new BadRequestException('项目不存在');
    }
    const hasPermission = await this.editorService.checkAuth(
      project,
      'edit',
      u.id,
    );
    if (!hasPermission) {
      throw new BadRequestException('您无权访问该项目');
    }

    return this.versionControlService.getVersionFiles(commitId);
  }

  @ApiOperation({ summary: '重置项目版本控制 - 清理所有版本数据' })
  @UseGuards(JwtAuthGuard)
  @Post('reset')
  async resetVersionControl(
    @Body() params: { projectId: string },
    @CurrentUser() u: UserEntity,
  ) {
    const { projectId } = params;

    // 检查项目权限
    const project = await this.projectModel.findById(projectId);
    if (!project) {
      throw new BadRequestException('项目不存在');
    }
    const hasPermission = await this.editorService.checkAuth(
      project,
      'edit',
      u.id,
    );
    if (!hasPermission) {
      throw new BadRequestException('您无权操作该项目');
    }

    // 删除所有相关数据
    const [deletedCommits, deletedSnapshots, deletedVersionState] =
      await Promise.all([
        this.versionControlService['commitModel'].deleteMany({ projectId }),
        this.versionControlService['fileSnapshotModel'].deleteMany({
          projectId,
        }),
        this.versionControlService['versionStateModel'].deleteMany({
          projectId,
        }),
      ]);

    return {
      success: true,
      message: '版本控制已重置',
      deleted: {
        commits: deletedCommits.deletedCount,
        snapshots: deletedSnapshots.deletedCount,
        versionStates: deletedVersionState.deletedCount,
      },
    };
  }

  // ==================== 文件变更记录 API (新增) ====================

  @ApiOperation({ summary: '获取文件的下一个版本号' })
  @UseGuards(JwtAuthGuard)
  @Get('next-version/:projectId')
  async getNextVersion(
    @Param('projectId') projectId: string,
    @CurrentUser() u: UserEntity,
    @Query('path') path: string,
  ) {
    // 检查项目权限
    const project = await this.projectModel.findById(projectId);
    if (!project) {
      throw new BadRequestException('项目不存在');
    }
    const hasPermission = await this.editorService.checkAuth(
      project,
      'edit',
      u.id,
    );
    if (!hasPermission) {
      throw new BadRequestException('您无权访问该项目');
    }

    if (!path) {
      throw new BadRequestException('文件路径不能为空');
    }

    const nextVersion = await this.versionControlService.getNextVersion(
      projectId,
      path,
    );

    return {
      success: true,
      nextVersion,
      path,
    };
  }

  @ApiOperation({ summary: '获取指定版本的文件内容' })
  @UseGuards(JwtAuthGuard)
  @Get('file-content/:projectId')
  async getFileContent(
    @Param('projectId') projectId: string,
    @CurrentUser() u: UserEntity,
    @Query('path') path: string,
    @Query('version') version?: string,
  ) {
    // 检查项目权限
    const project = await this.projectModel.findById(projectId);
    if (!project) {
      throw new BadRequestException('项目不存在');
    }
    const hasPermission = await this.editorService.checkAuth(
      project,
      'edit',
      u.id,
    );
    if (!hasPermission) {
      throw new BadRequestException('您无权访问该项目');
    }

    if (!path) {
      throw new BadRequestException('文件路径不能为空');
    }

    let content: string | null;

    if (version) {
      // 获取指定版本的内容
      const targetVersion = parseInt(version);
      if (isNaN(targetVersion) || targetVersion <= 0) {
        throw new BadRequestException('版本号必须是正整数');
      }
      content = await this.versionControlService.restoreFileVersion(
        projectId,
        path,
        targetVersion,
      );
    } else {
      // 获取最新版本的内容
      content = await this.versionControlService.getLatestFileContent(
        projectId,
        path,
      );
    }

    if (content === null) {
      throw new BadRequestException('文件内容不存在或版本不存在');
    }

    return {
      success: true,
      content,
      path,
      version: version || 'latest',
    };
  }

  @ApiOperation({ summary: '获取文件变更历史记录' })
  @UseGuards(JwtAuthGuard)
  @Get('changes/:projectId')
  async getFileChanges(
    @Param('projectId') projectId: string,
    @CurrentUser() u: UserEntity,
    @Query('path') path?: string,
    @Query('startTime') startTime?: string,
    @Query('endTime') endTime?: string,
    @Query('limit') limit?: string,
    @Query('skip') skip?: string,
    @Query('sortBy') sortBy?: string,
    @Query('sortOrder') sortOrder?: 'asc' | 'desc',
    @Query('excludeDocFiles') excludeDocFiles?: string, // 🆕 是否排除 .doc 文件
  ) {
    // 检查项目权限
    const project = await this.projectModel.findById(projectId);
    if (!project) {
      throw new BadRequestException('项目不存在');
    }
    const hasPermission = await this.editorService.checkAuth(
      project,
      'edit',
      u.id,
    );
    if (!hasPermission) {
      throw new BadRequestException('您无权访问该项目');
    }

    // 调用服务获取变更记录
    const changes = await this.versionControlService.getFileChanges({
      projectId,
      path,
      startTime: startTime ? Number(startTime) : undefined,
      endTime: endTime ? Number(endTime) : undefined,
      limit: limit ? Number(limit) : 20,
      skip: skip ? Number(skip) : 0,
      sortBy: sortBy || 'timestamp',
      sortOrder: sortOrder || 'desc',
      excludeDocFiles: excludeDocFiles === 'true', // 🆕 转换为布尔值
    });

    return {
      success: true,
      changes: changes.changes,
      total: changes.total,
      hasMore: changes.hasMore,
    };
  }

  @ApiOperation({ summary: '记录文件变更' })
  @UseGuards(JwtAuthGuard)
  @Post('changes')
  async recordFileChange(
    @Body()
    params: {
      projectId: string;
      path: string;
      action: 'add' | 'modify' | 'delete';
      content?: string;
      previousContent?: string;
      diff?: string; // 🆕 接收前端的 unified diff
      contentHash?: string; // 🆕 接收前端的内容哈希
      author?: string;
      message?: string;
    },
    @CurrentUser() u: UserEntity,
  ) {
    const { projectId } = params;

    // 检查项目权限
    const project = await this.projectModel.findById(projectId);
    if (!project) {
      throw new BadRequestException('项目不存在');
    }
    const hasPermission = await this.editorService.checkAuth(
      project,
      'edit',
      u.id,
    );
    if (!hasPermission) {
      throw new BadRequestException('您无权操作该项目');
    }

    // 记录文件变更
    const change = await this.versionControlService.recordFileChange({
      ...params,
      userId: u.id,
    });

    return {
      success: true,
      change,
      message: '文件变更记录成功',
    };
  }

  @ApiOperation({ summary: '批量同步文件变更记录' })
  @UseGuards(JwtAuthGuard)
  @Post('sync-changes')
  async syncFileChanges(
    @Body()
    params: {
      projectId: string;
      changes: Array<{
        path: string;
        action: 'add' | 'modify' | 'delete';
        content?: string;
        previousContent?: string;
        timestamp: number;
        author?: string;
        version: number;
      }>;
    },
    @CurrentUser() u: UserEntity,
  ) {
    const { projectId } = params;

    // 检查项目权限
    const project = await this.projectModel.findById(projectId);
    if (!project) {
      throw new BadRequestException('项目不存在');
    }
    const hasPermission = await this.editorService.checkAuth(
      project,
      'edit',
      u.id,
    );
    if (!hasPermission) {
      throw new BadRequestException('您无权操作该项目');
    }

    // 批量同步变更记录
    const syncedChanges = await this.versionControlService.syncFileChanges({
      projectId,
      changes: params.changes,
      userId: u.id,
    });

    return {
      success: true,
      syncedCount: syncedChanges.length,
      changes: syncedChanges,
      message: '文件变更同步成功',
    };
  }
}
